{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "import lightgbm as lgb\n",
    "import numpy as np\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn import metrics\n",
    "from sklearn.metrics import accuracy_score\n",
    "import time\n",
    "from pyspark.sql import SparkSession\n",
    "from concurrent.futures import ThreadPoolExecutor\n",
    "from sklearn.ensemble import VotingClassifier\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.ensemble import BaggingClassifier\n",
    "from sklearn.neural_network import MLPClassifier\n",
    "from sklearn.svm import SVC\n",
    "import xgboost as xgb\n",
    "import warnings\n",
    "from catboost import CatBoostClassifier\n",
    "from sklearn.ensemble import AdaBoostClassifier\n",
    "from sklearn.ensemble import GradientBoostingClassifier\n",
    "from sklearn.model_selection import RandomizedSearchCV\n",
    "from skdist.distribute.search import DistGridSearchCV\n",
    "from sklearn.ensemble import BaggingClassifier,RandomForestClassifier,ExtraTreesClassifier,GradientBoostingClassifier\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "all_data = pd.read_csv('data_demo4.csv')\n",
    "train_all_data=all_data[:28000]\n",
    "test_all_data=all_data[28000:]\n",
    "train_all_data[\"type\"] = train_all_data[\"type\"].map({'围网':0,'刺网':1,'拖网':2})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# train_all_data = pd.read_hdf('data/train_transform.h5')\n",
    "# test_all_data = pd.read_hdf('data/test_transform.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = train_all_data.drop(['ID','type'], axis=1)\n",
    "y_train = train_all_data[\"type\"]\n",
    "X_test = test_all_data.drop(['ID','type'], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#X_train, X_test, y_train, y_test = train_test_split(X_train, y_train, test_size=0.3, random_state=42)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def cv(X_train, X_test, y_train, model, nfold, seed, num_classes=3,knn=False):\n",
    "    train_pred = np.zeros((len(X_train), num_classes))\n",
    "    test_pred = np.zeros((len(X_test), num_classes))\n",
    "    \n",
    "    kfolder = StratifiedKFold(n_splits=nfold, shuffle=True, random_state=seed)\n",
    "    for fold_id, (trn_idx, val_idx) in enumerate(kfolder.split(X_train,y_train)):\n",
    "        x_tr = X_train.iloc[trn_idx]; x_te = X_train.iloc[val_idx]\n",
    "        y_tr = y_train.iloc[trn_idx]; y_te = y_train.iloc[val_idx]\n",
    "        \n",
    "        print(f'\\nFold_{fold_id}  ==========================================\\n')\n",
    "        if not knn:\n",
    "            model.fit(x_tr, y_tr,eval_set=[(x_tr, y_tr), (x_te, y_te)])\n",
    "        else:\n",
    "            model.fit(x_tr, y_tr)\n",
    "            \n",
    "        val_pred = model.predict_proba(x_te)\n",
    "        train_pred[val_idx] += val_pred\n",
    "        val_pred = np.argmax(val_pred, axis=1)\n",
    "        print(fold_id, 'f1', metrics.f1_score(y_te, val_pred, average='macro'))\n",
    "        \n",
    "        test_pred += model.predict_proba(X_test)\n",
    "    print(fold_id, 'f1', metrics.f1_score(y_train, np.argmax(train_pred, axis=1), average='macro'))\n",
    "    return train_pred,test_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def train():\n",
    "    voting_clf = VotingClassifier(estimators=[\n",
    "                (\"lgb_clf\",lgb.LGBMClassifier(learning_rate=0.22149993885702932,\n",
    "                                             min_child_samples=7, #它的值取决于训练数据的样本个树和num_leaves. 将其设置的较大可以避免生成一个过深的树, 但有可能导致欠拟合。\n",
    "                                             max_depth=7, #设置树深度，深度越大可能过拟合\n",
    "                                             lambda_l1=2,boosting=\"gbdt\",objective=\"multiclass\",\n",
    "                                             n_estimators=2400,metric='multi_error',num_class=3,\n",
    "                                             feature_fraction=0.75,bagging_fraction=0.85,seed=99,\n",
    "                                             num_threads=20,verbose=-1,n_jobs=-1,device=\"cpu\")),\n",
    "                (\"gdbt_clf\",GradientBoostingClassifier(n_estimators=1200, max_depth=9, \n",
    "                                                            min_samples_split=6, learning_rate=0.22461383601711735)),\n",
    "                (\"xgb_clf\",xgb.XGBClassifier(max_depth=6,learning_rate=0.16886074437000803,n_estimators=1000,\n",
    "                                      silent=True,objective='multi:softmax')),\n",
    "#                 (\"cat_clf\",CatBoostClassifier(iterations=1700, depth=6,learning_rate=0.278870430879049)),\n",
    "    #             (\"adaboost_clf\",AdaBoostClassifier(DecisionTreeClassifier(max_depth=9, min_samples_split=20, min_samples_leaf=5),\n",
    "    #                          algorithm=\"SAMME\",\n",
    "    #                          n_estimators=1000, learning_rate=0.7))\n",
    "            ],voting=\"soft\")\n",
    "    voting_train_pred,voting_test_pred=cv(X_train, X_test, y_train, voting_clf, 3, 2020,knn=True)\n",
    "    return voting_train_pred,voting_test_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Fold_0  ==========================================\n",
      "\n",
      "0 f1 0.9253977350585609\n",
      "\n",
      "Fold_1  ==========================================\n",
      "\n",
      "1 f1 0.9211817202385196\n",
      "\n",
      "Fold_2  ==========================================\n",
      "\n",
      "2 f1 0.9265490205098016\n",
      "2 f1 0.9243769605630948\n",
      "2352.1653456687927\n"
     ]
    }
   ],
   "source": [
    "start = time.time()\n",
    "\n",
    "with ThreadPoolExecutor(max_workers=10) as t: \n",
    "    f1 = t.submit(train)\n",
    "    voting_train_pred,voting_test_pred = f1.result()\n",
    "\n",
    "end = time.time()\n",
    "print(str(end-start))  #841.635686"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "plabels = np.argmax(voting_train_pred, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "oof f1 0.9243769605630948\n",
      "train accuracy 0.9386785714285715\n"
     ]
    }
   ],
   "source": [
    "print('oof f1', metrics.f1_score(y_train,plabels, average='macro'))\n",
    "print('train accuracy', accuracy_score(y_train,plabels))\n",
    "# oof f1 0.9243769605630948\n",
    "# train accuracy 0.9386785714285715"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "生产"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>start_date</th>\n",
       "      <th>start_hour</th>\n",
       "      <th>end_date</th>\n",
       "      <th>end_hour</th>\n",
       "      <th>work_days</th>\n",
       "      <th>work_seconds</th>\n",
       "      <th>nunique_x</th>\n",
       "      <th>mean_x</th>\n",
       "      <th>std_x</th>\n",
       "      <th>...</th>\n",
       "      <th>x_max-min</th>\n",
       "      <th>y_max-min</th>\n",
       "      <th>rec_area</th>\n",
       "      <th>slope</th>\n",
       "      <th>short_r</th>\n",
       "      <th>long_r</th>\n",
       "      <th>direction_miss_rate</th>\n",
       "      <th>speed_miss_rate</th>\n",
       "      <th>direct&amp;speed_miss_rate</th>\n",
       "      <th>type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>28000</th>\n",
       "      <td>7713</td>\n",
       "      <td>16</td>\n",
       "      <td>18</td>\n",
       "      <td>17</td>\n",
       "      <td>11</td>\n",
       "      <td>0</td>\n",
       "      <td>62475</td>\n",
       "      <td>3</td>\n",
       "      <td>6.180026e+06</td>\n",
       "      <td>35.042867</td>\n",
       "      <td>...</td>\n",
       "      <td>202.538733</td>\n",
       "      <td>3.823357</td>\n",
       "      <td>7.743779e+02</td>\n",
       "      <td>0.018877</td>\n",
       "      <td>101.287370</td>\n",
       "      <td>101.287447</td>\n",
       "      <td>0.388350</td>\n",
       "      <td>0.233010</td>\n",
       "      <td>0.126214</td>\n",
       "      <td>测试</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28001</th>\n",
       "      <td>7713</td>\n",
       "      <td>16</td>\n",
       "      <td>1</td>\n",
       "      <td>16</td>\n",
       "      <td>18</td>\n",
       "      <td>0</td>\n",
       "      <td>62476</td>\n",
       "      <td>96</td>\n",
       "      <td>6.198116e+06</td>\n",
       "      <td>8423.615062</td>\n",
       "      <td>...</td>\n",
       "      <td>26622.777759</td>\n",
       "      <td>11316.262147</td>\n",
       "      <td>3.012703e+08</td>\n",
       "      <td>0.425059</td>\n",
       "      <td>20821.683730</td>\n",
       "      <td>8836.375290</td>\n",
       "      <td>0.038835</td>\n",
       "      <td>0.038835</td>\n",
       "      <td>0.019417</td>\n",
       "      <td>测试</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28002</th>\n",
       "      <td>7713</td>\n",
       "      <td>15</td>\n",
       "      <td>7</td>\n",
       "      <td>16</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>63097</td>\n",
       "      <td>69</td>\n",
       "      <td>6.184735e+06</td>\n",
       "      <td>15096.683250</td>\n",
       "      <td>...</td>\n",
       "      <td>34219.912457</td>\n",
       "      <td>19279.311503</td>\n",
       "      <td>6.597364e+08</td>\n",
       "      <td>0.563395</td>\n",
       "      <td>30173.839096</td>\n",
       "      <td>16253.406417</td>\n",
       "      <td>0.077670</td>\n",
       "      <td>0.029126</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>测试</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28003</th>\n",
       "      <td>7713</td>\n",
       "      <td>14</td>\n",
       "      <td>12</td>\n",
       "      <td>15</td>\n",
       "      <td>7</td>\n",
       "      <td>0</td>\n",
       "      <td>69056</td>\n",
       "      <td>5</td>\n",
       "      <td>6.166233e+06</td>\n",
       "      <td>3292.015566</td>\n",
       "      <td>...</td>\n",
       "      <td>15341.362559</td>\n",
       "      <td>10683.819492</td>\n",
       "      <td>1.639043e+08</td>\n",
       "      <td>0.696406</td>\n",
       "      <td>10572.960364</td>\n",
       "      <td>15240.579932</td>\n",
       "      <td>0.223301</td>\n",
       "      <td>0.242718</td>\n",
       "      <td>0.097087</td>\n",
       "      <td>测试</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28004</th>\n",
       "      <td>8077</td>\n",
       "      <td>13</td>\n",
       "      <td>4</td>\n",
       "      <td>13</td>\n",
       "      <td>23</td>\n",
       "      <td>0</td>\n",
       "      <td>68997</td>\n",
       "      <td>103</td>\n",
       "      <td>6.093017e+06</td>\n",
       "      <td>3526.983729</td>\n",
       "      <td>...</td>\n",
       "      <td>11976.614480</td>\n",
       "      <td>42285.885611</td>\n",
       "      <td>5.064417e+08</td>\n",
       "      <td>3.530704</td>\n",
       "      <td>21853.892951</td>\n",
       "      <td>22119.560858</td>\n",
       "      <td>0.009615</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>测试</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 61 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         ID  start_date  start_hour  end_date  end_hour  work_days  \\\n",
       "28000  7713          16          18        17        11          0   \n",
       "28001  7713          16           1        16        18          0   \n",
       "28002  7713          15           7        16         1          0   \n",
       "28003  7713          14          12        15         7          0   \n",
       "28004  8077          13           4        13        23          0   \n",
       "\n",
       "       work_seconds  nunique_x        mean_x         std_x  ...     x_max-min  \\\n",
       "28000         62475          3  6.180026e+06     35.042867  ...    202.538733   \n",
       "28001         62476         96  6.198116e+06   8423.615062  ...  26622.777759   \n",
       "28002         63097         69  6.184735e+06  15096.683250  ...  34219.912457   \n",
       "28003         69056          5  6.166233e+06   3292.015566  ...  15341.362559   \n",
       "28004         68997        103  6.093017e+06   3526.983729  ...  11976.614480   \n",
       "\n",
       "          y_max-min      rec_area     slope       short_r        long_r  \\\n",
       "28000      3.823357  7.743779e+02  0.018877    101.287370    101.287447   \n",
       "28001  11316.262147  3.012703e+08  0.425059  20821.683730   8836.375290   \n",
       "28002  19279.311503  6.597364e+08  0.563395  30173.839096  16253.406417   \n",
       "28003  10683.819492  1.639043e+08  0.696406  10572.960364  15240.579932   \n",
       "28004  42285.885611  5.064417e+08  3.530704  21853.892951  22119.560858   \n",
       "\n",
       "       direction_miss_rate  speed_miss_rate  direct&speed_miss_rate  type  \n",
       "28000             0.388350         0.233010                0.126214    测试  \n",
       "28001             0.038835         0.038835                0.019417    测试  \n",
       "28002             0.077670         0.029126                0.000000    测试  \n",
       "28003             0.223301         0.242718                0.097087    测试  \n",
       "28004             0.009615         0.000000                0.000000    测试  \n",
       "\n",
       "[5 rows x 61 columns]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_all_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "sub = test_all_data[['ID']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "production_pred = np.argmax(voting_test_pred, axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2    0.636125\n",
      "0    0.244625\n",
      "1    0.119250\n",
      "Name: pred, dtype: float64\n"
     ]
    }
   ],
   "source": [
    "sub['pred'] = production_pred\n",
    "\n",
    "print(sub['pred'].value_counts(1))\n",
    "sub['pred'] = sub['pred'].map({0:'围网',1:'刺网',2:'拖网'})\n",
    "sub.to_csv('data/result.csv', index=None, header=None)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
